package com.kelai.jms.handel.queue;

import com.kelai.callback.IdCallback;
import com.kelai.common.IServiceLayer;
import com.kelai.common.PersistObject;
import com.kelai.common.exception.BreezeeException;
import com.kelai.domain.DeviceDataEntity;
import com.kelai.domain.DeviceEntity;
import com.kelai.domain.DevicePackageDataEntity;
import com.kelai.domain.DeviceStateDataEntity;
import com.kelai.jms.RedisMessageChannelEnum;
import com.kelai.jms.handel.RedisQueueMessageDelegateHandle;
import com.kelai.jms.message.queue.DeviceDataPacketQueueMessage;
import com.kelai.response.JsonResponse;
import com.kelai.service.IDeviceDataService;
import com.kelai.service.IDevicePackageDataService;
import com.kelai.service.IDeviceStateDataService;
import com.kelai.utils.SystemTool;
import javafx.util.Callback;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;


/**
 * 设备数据包解析入库异步执行类
 * Created by Luffy on 2017/08/17.
 */
public class DeviceDataPacketQueueMessageHandle extends RedisQueueMessageDelegateHandle<DeviceDataPacketQueueMessage, Object> {

    private final static Logger logger = LoggerFactory.getLogger(DeviceDataPacketQueueMessageHandle.class);
    @Resource
    private IDeviceDataService deviceDataService;
    @Resource
    private IDevicePackageDataService devicePackageDataService;
    @Resource
    private IDeviceStateDataService deviceStateDataService;
    @Resource
    private IdCallback idCallback;

    public DeviceDataPacketQueueMessageHandle() {
        super(RedisMessageChannelEnum.DEVICE_DATA_PACKET_QUEUE_WEBSERVICE);
    }

    @Override
    protected Object doExecute(DeviceDataPacketQueueMessage message) throws Exception {
        cacheData(message.getDeviceDataPacket());
//        test(message.getDeviceDataPacket());
        return null;
    }

    private void cacheData(DevicePackageDataEntity devicePackageDataEntity) {

//        LocalDateTime ln = LocalDateTime.now();
//        ln = ln.plusDays(-7);
        //由于存在时区的不同，我们往后延伸24小时
        LocalDateTime now = LocalDateTime.now();
        Long nowt = Long.parseLong(now.plusHours(24).toString().replaceAll("-", "").replaceAll("T", "").replaceAll(":", "").substring(0, 14));
        Long nowp = Long.parseLong(now.plusMonths(-3).toString().replaceAll("-", "").replaceAll("T", "").replaceAll(":", "").substring(0, 14));


        String data = devicePackageDataEntity.getData();
        String sn = getSn(devicePackageDataEntity.getState().substring(4, 12)).toUpperCase();
        devicePackageDataEntity.setSn(sn);
        //logger.info("~~~~~~设备"+sn+"数据入库开始");
        long startTime = System.currentTimeMillis();    //获取开始时间
        Integer focus = Integer.decode("0x" + devicePackageDataEntity.getState().substring(12, 14));
        Integer battery = Integer.decode("0x" + devicePackageDataEntity.getState().substring(18, 20));
        DeviceEntity device = (DeviceEntity) devicePackageDataEntity.getProperties().get("device");
        Boolean isSonyDevice = false;
        if(device != null){
            if(Objects.equals("9236b103947f4f71b261bcf958286b2c",device.findCustomerId())){
                isSonyDevice = true;
            }
//            logger.info("~~得到设备ID~~" + device.getId());
        }else{
//            logger.info("~~设备:" +sn+"不存在");
        }

//        long a = System.currentTimeMillis();    //获取开始时间
        String nowStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
//        DevicePackageDataEntity dpde = new DevicePackageDataEntity();
//
//        dpde.getProperties().put("sn", sn);
//        dpde.getProperties().put("data", data);
//        dpde.getProperties().put("receiveDateTime_gt", BreezeeUtils.localDateTime2Date(ln));
//
//        List list = devicePackageDataService.listAll(dpde);
        devicePackageDataEntity.setRemark("async");
//        if (CollectionUtils.isEmpty(list)) {
//            _saveInfo(devicePackageDataService, devicePackageDataEntity, new Callback<DevicePackageDataEntity, Object>() {
//                @Override
//                public Object call(DevicePackageDataEntity param) {
//                    param.setCode(param.getId());
//                    return null;
//                }
//            });
            String[] ss = data.split(",");
            long b = System.currentTimeMillis();    //获取开始时间
//            logger.info("判断设备数据包是否重复并插入数据库，耗时： " + (b - a) + "ms");
            if (Objects.equals(devicePackageDataEntity.getProperties().get("flag"), true)) {
                DeviceDataEntity de;
                String happenTimeStr = "";
                Long happenTime;
                Integer dxIn = 0;
                Integer dxOut = 0;
                for (String s : ss) {
                    long a1 = System.currentTimeMillis();    //获取开始时间
                    dxIn = Integer.decode("0x" + s.substring(20, 22) + s.substring(18, 20) + s.substring(16, 18) + s.substring(14, 16));
                    dxOut = Integer.decode("0x" + s.substring(28, 30) + s.substring(26, 28) + s.substring(24, 26) + s.substring(22, 24));
                    if (dxIn + dxOut >= 0) {
                        //100B1E131600000000000000000000D5FD
                        happenTimeStr = "20" + deHexFormat(s.substring(0, 2)) + deHexFormat(s.substring(2, 4))
                                + deHexFormat(s.substring(4, 6)) + deHexFormat(s.substring(6, 8))
                                + deHexFormat(s.substring(8, 10)) + deHexFormat(s.substring(10, 12));
                        happenTime = Long.parseLong(happenTimeStr);
                        if (!checkHappenTime(happenTime, nowt, nowp)) {
                            continue;
                        }

                        de = deviceDataService.findByCode(sn + happenTimeStr);
                        if (de == null) {
                            de = _dataDevice(sn, happenTimeStr , device);
                        } else {
                            continue;
//                            dxIn += (de.getDxin() == null ? 0 : de.getDxin());
//                            dxOut += (de.getDxout() == null ? 0 : de.getDxout());
                        }
                        de.setFocus(focus);
                        de.setBattery(battery);
                        if (device != null && device.getDirection() == 0) {
                            de.setDxin(dxOut);
                            de.setDxout(dxIn);
                            // FIXME 原来的判断条件貌似有问题} else if (device == null || device.getDirection() == 1) {
                        } else if (device != null && device.getDirection() == 1) {
                            de.setDxin(dxIn);
                            de.setDxout(dxOut);
                        }
                        if (devicePackageDataEntity.getId() != null)
                            de.setDevicePackageData(devicePackageDataEntity);
                        de.setRemark("async");
                        _saveInfo(deviceDataService, de);
                    }

                    /*保存索尼中国的设备状态流水信息*/
                    if(isSonyDevice){
                        DeviceStateDataEntity dede = new DeviceStateDataEntity();
                        dede.setDevice(device);
                        if(StringUtils.isNotEmpty(happenTimeStr)){
                            dede.setHappenTime(happenTimeStr);
                        }
                        dede.setReceiveTime(nowStr);
                        dede.setFocus(device.getFocus());
                        dede.setBattery(device.getVoltage());
                        dede.setDxin(dxIn);
                        dede.setDxout(dxOut);
                        _saveInfo(deviceStateDataService, dede, new Callback<DeviceStateDataEntity, Object>() {
                            @Override
                            public Object call(DeviceStateDataEntity param) {
                                param.setCode(param.getId());
                                return null;
                            }
                        });

                    }
                    long b1 = System.currentTimeMillis();    //获取开始时间
                    //logger.info("查找和更新流水记录，耗时： " + (b1 - a1) + "ms");
                }
//            }
        }
        long endTime = System.currentTimeMillis();    //获取结束时间
        //logger.info("设备"+sn+"数据入库结束，共耗时： " + (endTime - startTime) + "ms~~~~~~");
    }

    private static String getSn(String hexString) {
        String hv = null;
        StringBuilder sb = new StringBuilder();
        byte[] bb = SystemTool.convert16HexToByte(hexString);
        for (byte b : bb) {
            int v = b & 0xFF;
            hv = Integer.toHexString(v);
            hv = (hv.length() == 1 ? "0" + hv : hv);
            sb.insert(0, hv);
        }
        return sb.toString();
    }

    private static String deHexFormat(String s) {
        Integer i = Integer.decode("0x" + s);
        return i < 10 ? "0" + i : i.toString();
    }


    private DeviceDataEntity _dataDevice(String sn, String t, DeviceEntity device) {
        DeviceDataEntity de = new DeviceDataEntity();
        de.setCode(sn + t);
        de.setName(sn);
        de.setSn(sn);
        de.setHappenTime(Long.parseLong(t));
        if (device != null) {
            de.setDevice(device);
            if (device.getCustomer() != null) {
                de.setCustomer(device.getCustomer());
                de.setCustomerId(device.getCustomer().getTopCustomerId());
            }
        }
        return de;
    }

    protected <T extends PersistObject> JsonResponse _saveInfo(IServiceLayer service, T info, Callback... callback) {
        try {
            Callback cb = idCallback;
            if (cb != null) {
                List<Callback> l = new ArrayList<>(Arrays.asList(callback));
                Callback[] cbs = new Callback[l.size()];
                l.add(0, idCallback);
                service.saveInfo(info, l.toArray(cbs));
            } else {
                service.saveInfo(info, callback);
            }
        } catch (BreezeeException e) {
            e.printStackTrace();
            return JsonResponse.ERROR(e.getMessage());
        }
        return JsonResponse.buildSingle(info);
    }

    /**
     * 仅供测试使用
     * @param devicePackageDataEntity
     */
    private void test(DevicePackageDataEntity devicePackageDataEntity){
        try {
            Thread.currentThread().sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        _saveInfo(devicePackageDataService, devicePackageDataEntity, new Callback<DevicePackageDataEntity, Object>() {
            @Override
            public Object call(DevicePackageDataEntity param) {
                param.setCode(param.getId());
                return null;
            }
        });
    }

    /**
     * 发生时间在三个月前的，过滤掉
     * 发生时间在未来的过滤掉
     *
     * @param happenTimeStr
     * @param nowt
     * @param nowp
     * @return
     */
    private boolean checkHappenTime(Long happenTimeStr, Long nowt, Long nowp) {
        //20190115215411
        if (happenTimeStr > nowt) {
            return false;
        }
        if (happenTimeStr < nowp) {
            return false;
        }
        return true;
    }
}
